//****************************************************
// Porman Project 2
// Filename: CFXObject.h
// Date: 2008/10/02
// Author: KengYu Lin
// Modify:
//****************************************************
#ifndef _CFXOBJECT_H
#define _CFXOBJECT_H
#include <vector>
#include "CTextureObject.h"

namespace Porman
{

namespace GL
{

class CTextureBaseObject;
class CPass;
class CTechnique;
class CFXObject;

class CFXObject : public CBaseObject
{
    friend class CRenderDevice;
public:
    class CTechnique
    {
        friend class CRenderDevice;
        friend class CFXObject;
    public:
        class CPass
        {
            friend class CRenderDevice;
            friend class CTechnique;
        public:
            PGL_API const char* getPassName( void );
            PGL_API std::string getCode( EPassDomain enumDomain, EPassCodeType enumCodeType );

        protected:
            CPass( CGpass Pass );
            virtual ~CPass( void );
            void _enableVaryingShaderParameters( void );
            void _disableVaryingShaderParameters( void );
            int _getSemanticSize( void );
            SSemantic* _getSemantic( int iIndex );

        protected:
            CGpass m_cgPass;
            CTechnique* m_pParentTech;
            std::vector<SSemantic> m_vectSemantic;
        };

    public:
        PGL_API CTechnique::CPass* getNamedPass( const char* sName );
        PGL_API CTechnique::CPass* getIndexedPass( int iIndex );
        PGL_API int getNumOfPass( void );

        PGL_API const char* getTechName( void );
        PGL_API ERESULT validateTechs( std::string* pMsg = NULL );
        PGL_API bool isValidated( void );

    protected:
        CTechnique( CGtechnique Tech );
        virtual ~CTechnique( void );

    protected:
        CGtechnique m_cgTechnique;
        std::vector<CPass*> m_vectPasses;
        CFXObject* m_pParentFXObj;
    };

public:
    PGL_API virtual void setName( const char* pName ) { m_sName = std::string("FxObj_") + std::string( pName ); }

    PGL_API CFXObject::CTechnique* getNamedTech( const char* sName );
    PGL_API CFXObject::CTechnique* getIndexedTech( int iIndex );
    PGL_API int getNumOfTech( void );

    PGL_API ERESULT setArraySize( const HSHADERPARAM* pParam, const int& iSize );
    PGL_API ERESULT setArrayMultiDimSize( const HSHADERPARAM* pParam, const int* pSize );
    PGL_API ERESULT setParameterFloat( const HSHADERPARAM* pParam, float fVal );
    PGL_API ERESULT setParameterFloatArrayRow( const HSHADERPARAM* pParam, unsigned int iNumElement, const float* fArray );
    PGL_API ERESULT setParameterFloatArrayCol( const HSHADERPARAM* pParam, unsigned int iNumElement, const float* fArray );
    PGL_API ERESULT setSampler( const HSHADERPARAM* pParam, CTextureBaseObject* pTextureObj );
    PGL_API ERESULT setSampler( const HSHADERPARAM* pParam, const CSamplerState* pSampler, CTextureBaseObject* pTextureObj );

    PGL_API ERESULT setArraySize( const char* sParam, const int& iSize );
    PGL_API ERESULT setArrayMultiDimSize( const char* sParam, const int* pSize );
    PGL_API ERESULT setParameterFloat( const char* sParam, float fVal );
    PGL_API ERESULT setParameterFloatArrayRow( const char* sParam, unsigned int iNumElement, const float* fArray );
    PGL_API ERESULT setParameterFloatArrayCol( const char* sParam, unsigned int iNumElement, const float* fArray );
    PGL_API ERESULT setSampler( const char* sParam, CTextureBaseObject* pTextureObj );
    PGL_API ERESULT setSampler( const char* sParam, const CSamplerState* pSampler, CTextureBaseObject* pTextureObj );
    PGL_API ERESULT setInterface( const char* sInterface, const HSHADERPARAM* pParam );

    PGL_API ERESULT getParameter( const char* sParam, HSHADERPARAM* pParam );
    PGL_API ERESULT getArrayDim( const char* sParam, int& iDim );
    PGL_API ERESULT getArrayDim( HSHADERPARAM* pParam, int& iDim );
    PGL_API ERESULT getArraySize( const char* sParam, int iDim,int& iSize );
    PGL_API ERESULT getArraySize( HSHADERPARAM* pParam, int iDim,int& iSize );
    PGL_API ERESULT getInstance( const char* sInstance, HSHADERPARAM* pParam );
    PGL_API ERESULT getInstanceArray( const char* sInstance, int iLength, HSHADERPARAM* pParam );
    PGL_API ERESULT getInstanceMultiDimArray( const char* sInstance, int iDim, const int* pLength, HSHADERPARAM* pParam );
    PGL_API ERESULT getInstanceParam( const char* sInstance, const HSHADERPARAM* pInParam, HSHADERPARAM* pOutParam );

protected:
    CFXObject( CRenderDevice* pDevice );
    virtual ~CFXObject( void );
    void _disableAllSamplerParameters( void );
    void _getSamplerStateFromFX( CGparameter param, CSamplerState& Sampler );
    void _clearParam( void );

protected:
    CRenderDevice* m_pDevice;
    CGeffect m_cgEffect;
    unsigned int m_uiParamID;
    unsigned int m_uiSamplerParamID;
    std::vector<CTechnique*> m_vectTechs;
    std::vector<HSHADERPARAM> m_vectSamplerParams;
    std::vector<CGparameter> m_vectInstParams;
};

}//End namespace GL

}//End namespace Porman

#endif